package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.teenpatti.base.enums.ErrorCodeEnum;
import com.jule.teenpatti.base.enums.GameConst;
import com.jule.teenpatti.game.dao.bean.RoomConfigModel;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.PlayerStateEnum;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_ChangeCardAck_50013;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.service.TableService;
import com.jule.teenpatti.game.service.holder.CardOfTableHolder;
import com.jule.teenpatti.game.service.holder.RoomConfigHolder;
import com.jule.teenpatti.game.vavle.notice.NoticeBroadcastMessages;
import com.jule.teenpatti.log.service.LogReasons;
import com.google.common.primitives.Ints;
import io.netty.buffer.ByteBuf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 换牌
 */
public class JoloGame_ChangeCardReq_50013 extends ClientReq {
    private long time;
    private final static Logger logger = LoggerFactory.getLogger(JoloGame_ChangeCardReq_50013.class);

    public JoloGame_ChangeCardReq_50013(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_ChangeCardReq req;


    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        time = System.currentTimeMillis();
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_ChangeCardReq.parseFrom(blob);
        this.setTable(TableService.getInstance().getTable(header.gameId + "", req.getRoomId(), req.getTableId()));
    }

    @Override
    public void processImpl() throws Exception {
        logger.debug("收到消息-> " + functionId + " reqNum-> " + header.reqNum + "msg ->" + req.toString());
        JoloGame.JoloGame_ChangeCardAck.Builder ack = JoloGame.JoloGame_ChangeCardAck.newBuilder();
        String userId = req.getUserId();
        String roomId = req.getRoomId();
        String tableId = req.getTableId();
        String gameOrderId = req.getGameOrderId();

        try {
            AbstractTable table = getTable();
            PlayerInfo player = table.getPlayer(userId);

            int wantChangeCardId = req.getWantChangeCardId();
            RoomConfigModel roomConfig = RoomConfigHolder.getInstance().getRoomConfig(roomId);
            int changeCardScore = (int) roomConfig.getChangeCardFee();

            ack.setUserId(userId);
            ack.setRoomId(roomId);
            ack.setTableId(tableId);
            ack.setSeatNum(player.getSeatNum());
            ack.setGameOrderId(gameOrderId);
            ack.setCardId(wantChangeCardId);
            ack.setCurrPlayScore(player.getPlayScoreStore());

            if (player.getState().getValue() != PlayerStateEnum.beting.getValue()) {
                logger.error("player state invalid,can't bet. playerId->" + userId + ", state->" + player.getState());
                ack.setResult(-1).setResultMsg(ErrorCodeEnum.GAME_50013_1.getCode());
                ctx.writeAndFlush(new JoloGame_ChangeCardAck_50013(ack.build(), header));
                return;
            }


            //如果gameOrderId不一致，那么返回错误
            if (!gameOrderId.equals(table.getCurrGameOrderId())) {
                ack.setResult(-2);
                logger.error("GameOrderId不一致, req gameOrderId->" + gameOrderId);
                ack.setResultMsg(ErrorCodeEnum.GAME_50013_2.getCode());
                ctx.writeAndFlush(new JoloGame_ChangeCardAck_50013(ack.build(), header));
                return;
            }

            if (changeCardScore > player.getPlayScoreStore()) {
                ack.setResult(-3);
                logger.error("Player desktop score insufficient" + " -> " +
                        "desktopScore:" + player.getPlayScoreStore());
                ack.setResultMsg(ErrorCodeEnum.GAME_50013_3.getCode());
                ctx.writeAndFlush(new JoloGame_ChangeCardAck_50013(ack.build(), header));
                return;
            }

            int[] cardId = table.getChangeCard(userId);

            int[] handCards = player.getHandCards();
            List<Integer> list = new ArrayList<>(Ints.asList(handCards));
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i) == wantChangeCardId) {
                    list.remove(i);
                    list.add(cardId[0]);
                }
            }
            player.setHandCards(list.stream().mapToInt(i -> i).toArray());
            table.getChangeCards().add(wantChangeCardId);
            //更新玩家桌面的最新余额
            //player.setPlayScoreStore(player.getPlayScoreStore() - changeCardScore);
            player.minusPlayScoreStore(changeCardScore, LogReasons.CommonLogReason.GAME_CHANGECARD);
            ack.setCurrPlayScore(player.getPlayScoreStore());
            ctx.writeAndFlush(new JoloGame_ChangeCardAck_50013(ack.setResult(1).setCardId(cardId[0]).build(), header));

            table.setLastActionTime(System.currentTimeMillis());

            int changeCardFeeTips = (int) (changeCardScore - (changeCardScore * (roomConfig.getChangeCardFeeTips() * 0.01)));
            table.setTotalAlreadyBet(table.getTotalAlreadyBet() + changeCardFeeTips);
            //广播换牌
            NoticeBroadcastMessages.changeCard(table, player, wantChangeCardId, changeCardFeeTips);
            //发送通知
            NoticeBroadcastMessages.moneyChangeNotice(table,userId,player.getPlayScoreStore());
            long timeMillis = System.currentTimeMillis() - time;
            if (timeMillis > GameConst.COST_TIME) {
                LoggerUtils.performance.info("ChangeCardReq_50013,cost time:{},req:{}", timeMillis, req.toString());
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        } finally {
        }
    }
}
